home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 37 / Amiga Format CD37 (1999-02-16)(Future Publishing)(GB)(Track 1 of 3)[!][issue 1999-03].iso / -screenplay- / shareware / invasionforce / source / options.c < prev    next >
C/C++ Source or Header  |  1999-01-09  |  41KB  |  1,237 lines

  1. /*
  2.    options.c -- options editor module for Invasion Force
  3.    This module allows the user to edit the game options.
  4.    This source code is free.  You may make as many copies as you like.
  5. */
  6.  
  7. #include "global.h"
  8.  
  9. int high_player;      // i.e. the number of players
  10.  
  11. BOOL fmail = FALSE;
  12. BOOL modem = FALSE;
  13.  
  14. struct Window *opt_window;
  15. struct Gadget *minus_gad, *plus_gad, *pgads[9];
  16. struct Gadget *namefield, *rol_ptype;
  17. struct Gadget *mapfile_button, *mapfile_field;
  18.  
  19. // the slider gadgets
  20. struct Gadget *prod_slide, *att_slide, *def_slide, *aggr_slide;
  21.  
  22. // the integer gadgets
  23. struct Gadget *prod_int, *att_int, *def_int, *aggr_int;
  24.  
  25. // global game options
  26. struct Opt opt;
  27.  
  28. /*
  29.    The following debugging function should print the player information,
  30.    a good way to see if it was really retrieved from the Intuition gadgets
  31.    properly, and whether the program keeps it straight.
  32. */
  33.  
  34. void show_player(pnum)
  35. int pnum;
  36. {  // print play information
  37.    if (roster[pnum].type == NOPLAYER) {
  38.       sprintf(foo,"Player %d does not exist!\n");  print(foo);
  39.       return;
  40.    FI
  41.    sprintf(foo,"Info for player %d:\n",pnum);   print(foo);
  42.    sprintf(foo,"   Name: %s\n",roster[pnum].name);  print(foo);
  43.    switch (roster[pnum].type) {
  44.       case HUMAN:
  45.          sprintf(foo,"   Type: HUMAN\n");
  46.       case COMPUTER:
  47.          sprintf(foo,"   Type: COMPUTER\n");
  48.    }
  49.    print(foo);
  50. }
  51.  
  52.  
  53. void init_players()
  54. {  // set default player names and other values
  55.    int ctr = 0;
  56.    char *dflt_names[] = {
  57.       "NEUTRAL",
  58.       "General Havoc",
  59.       "Major Damage",
  60.       "Colonel Mustard",
  61.       "Sergeant Pepper",
  62.       "Commander McBragg",
  63.       "Flex Crush",
  64.       "Max Force",
  65.       "Hun Dread"
  66.    };
  67.    int color_table[] = {
  68.       WHITE, RED, LT_BLUE, ORANGE, GREEN, BROWN, PURPLE, GRAY, TAN
  69.    };
  70.  
  71.    for (; ctr<=8; ctr++) {
  72.       int ctr2;
  73.  
  74.       strcpy(roster[ctr].name,dflt_names[ctr]);
  75.       roster[ctr].type = HUMAN;
  76.       roster[ctr].status = ACTIVE;
  77.       roster[ctr].show = SHOW_ALL;
  78.       roster[ctr].color = color_table[ctr];
  79.       roster[ctr].prod = 50;
  80.       roster[ctr].def = roster[ctr].att = 0;
  81.       roster[ctr].aggr = 5;
  82.       roster[ctr].snd_vol = 45;
  83.       roster[ctr].msg_delay = 25;
  84.       roster[ctr].battle_delay = 50;
  85.       roster[ctr].soundfx = SOUND_ALL;
  86.       roster[ctr].autorpt = TRUE;
  87.       roster[ctr].show_production = TRUE;
  88.       roster[ctr].map = NULL;
  89.       NewList((struct List *)&roster[ctr].icons);
  90.       for (ctr2=0; ctr2<11; ctr2++) {
  91.          roster[ctr].eud[ctr2] = 0;
  92.          roster[ctr].ulc[ctr2] = 0;
  93.       OD
  94.    OD
  95.    roster[0].type = NOPLAYER;
  96.  
  97.    // while I'm here, I'll initialize all the OPT values as well
  98.    opt.gametype = 0;
  99.    opt.wrap = FALSE;
  100.    opt.defend_cities = FALSE;
  101.    opt.fortification = FALSE;
  102.    opt.stacking = FALSE;
  103.    opt.landmines = FALSE;
  104.    opt.seamines = FALSE;
  105. }
  106.  
  107.  
  108. /********************************************************************
  109. Cities have a maximum output of 100 industrial units (IU) per turn,
  110. assuming they are at 100% production efficiency.  So, at the default
  111. 50% efficiency they produce 50 IU per turn.  In this case a rifle unit
  112. would take five turns, or a total of 250 IU.  When a city is captured or
  113. its production is reset to another unit type, the work in progress (WIP)
  114. value is set to a negative number.  WIP = 0-(unit requirement)*0.2
  115.  
  116. In the default case, with a newly captured city producing rifles at 50%
  117. efficiency, it begins with a WIP of -50.  Thus, it will take six turns
  118. (and 300 IU) to produce the first rifle, five for each additional.
  119.  
  120. If the same city were turned over to cruisers (requiring 1500 IU), then
  121. it would begin at -300 WIP and take 36 turns for the first one, 30 for
  122. further cruisers.
  123. ********************************************************************/
  124.  
  125.  
  126. void change_ptype(code)
  127. int code;
  128. {  // user has change the type of player
  129.    PLAYER.type = (code ? COMPUTER : HUMAN);
  130.  
  131.    // if player is HUMAN, then disable computer aggressiveness gadgets
  132.    GT_SetGadgetAttrs(aggr_slide,opt_window,NULL,
  133.       GA_Disabled, !code,
  134.       TAG_END );
  135.    GT_SetGadgetAttrs(aggr_int,opt_window,NULL,
  136.       GA_Disabled, !code,
  137.       TAG_END);
  138. }
  139.  
  140. void change_gametype(code)
  141. int code;
  142. {  // user has changed the type of game
  143.    opt.gametype = (code ? 1 : 2);
  144.  
  145.    if(opt.gametype==1)
  146.         fmail = TRUE;
  147.    if(opt.gametype==2)
  148.         modem = TRUE;
  149. }
  150.  
  151. // take a new slider value and update everything that needs it
  152.  
  153. void read_slider(id_code,new_value)
  154. int id_code;
  155. UWORD new_value;
  156. {
  157.    struct Gadget *dest_integer;
  158.  
  159.    switch (id_code) {
  160.       case 0:
  161.          dest_integer = prod_int;
  162.          break;
  163.       case 1:
  164.          dest_integer = att_int;
  165.          break;
  166.       case 2:
  167.          dest_integer = def_int;
  168.          break;
  169.       case 3:
  170.       default:
  171.          dest_integer = aggr_int;
  172.    }
  173.    GT_SetGadgetAttrs(dest_integer,opt_window,NULL,
  174.       GTIN_Number, (WORD)new_value,
  175.       TAG_END);
  176. }
  177.  
  178.  
  179. // read a value from an integer gadget and
  180. // update everything that needs it
  181.  
  182. void read_integer(id_code)
  183. int id_code;
  184. {
  185.    long new_value;
  186.    long max_value=100L, min_value=1L;
  187.    struct Gadget *source, *dest;
  188.  
  189.    switch (id_code) {
  190.       case 0:
  191.          source = prod_int;
  192.          dest = prod_slide;
  193.          break;
  194.       case 1:
  195.          source = att_int;
  196.          dest = att_slide;
  197.          min_value = -8L;
  198.          max_value = 8L;
  199.          break;
  200.       case 2:
  201.          source = def_int;
  202.          dest = def_slide;
  203.          min_value = -8L;
  204.          max_value = 8L;
  205.          break;
  206.       case 3:
  207.       default:
  208.          source = aggr_int;
  209.          dest = aggr_slide;
  210.          min_value = 1L;
  211.          max_value = 10L;
  212.    }
  213.    new_value = ((struct StringInfo *)source->SpecialInfo)->LongInt;
  214.    if (new_value>max_value) {
  215.       new_value = max_value;
  216.       GT_SetGadgetAttrs(source,opt_window,NULL,
  217.          GTIN_Number, new_value,
  218.          TAG_END);
  219.    FI
  220.    if (new_value<min_value) {
  221.       new_value = min_value;
  222.       GT_SetGadgetAttrs(source,opt_window,NULL,
  223.          GTIN_Number, new_value,
  224.          TAG_END);
  225.    FI
  226.    GT_SetGadgetAttrs(dest,opt_window,NULL,
  227.       GTSL_Level, new_value,
  228.       TAG_END);
  229. }
  230.  
  231.  
  232. /*
  233.    update_player() updates all the player info gadgets with data
  234.    taken from the player data structures -- critical when the user
  235.    wants to edit or look at a different player
  236. */
  237.  
  238. void update_player()
  239. {  // update player gadgets to current values
  240.  
  241.    // first the player's name
  242.    GT_SetGadgetAttrs(namefield,opt_window,NULL,
  243.       GTST_String, PLAYER.name,
  244.       TAG_END );
  245.  
  246.    // player type: HUMAN or COMPUTER
  247.    GT_SetGadgetAttrs(rol_ptype,opt_window,NULL,
  248.       GTCY_Active, ((PLAYER.type==COMPUTER) ? 1:0),
  249.       TAG_END );
  250.  
  251.    // all the integer gadgets
  252.    GT_SetGadgetAttrs(prod_int,opt_window,NULL,
  253.       GTIN_Number, PLAYER.prod,
  254.       TAG_END);
  255.    GT_SetGadgetAttrs(att_int,opt_window,NULL,
  256.       GTIN_Number, PLAYER.att,
  257.       TAG_END);
  258.    GT_SetGadgetAttrs(def_int,opt_window,NULL,
  259.       GTIN_Number, PLAYER.def,
  260.       TAG_END);
  261.    GT_SetGadgetAttrs(aggr_int,opt_window,NULL,
  262.       GTIN_Number, PLAYER.aggr,
  263.       TAG_END);
  264.  
  265.    // all the slider gadgets
  266.    GT_SetGadgetAttrs(prod_slide,opt_window,NULL,
  267.       GTSL_Level, PLAYER.prod,
  268.       TAG_END);
  269.    GT_SetGadgetAttrs(att_slide,opt_window,NULL,
  270.       GTSL_Level, PLAYER.att,
  271.       TAG_END);
  272.    GT_SetGadgetAttrs(def_slide,opt_window,NULL,
  273.       GTSL_Level, PLAYER.def,
  274.       TAG_END);
  275.    GT_SetGadgetAttrs(aggr_slide,opt_window,NULL,
  276.       GTSL_Level, PLAYER.aggr,
  277.       TAG_END);
  278.  
  279.    // if player is HUMAN, then disable computer aggressiveness gadgets
  280.    GT_SetGadgetAttrs(aggr_slide,opt_window,NULL,
  281.       GA_Disabled, ((PLAYER.type==COMPUTER) ? 0:1),
  282.       TAG_END );
  283.    GT_SetGadgetAttrs(aggr_int,opt_window,NULL,
  284.       GA_Disabled, ((PLAYER.type==COMPUTER) ? 0:1),
  285.       TAG_END);
  286.  
  287.    // render the color indicator icon
  288.    px_plot_icon(RIFLE,260,72,PLAYER.color,ORDER_NONE,FALSE);
  289. }
  290.  
  291.  
  292. /*
  293.    store_player() substantially reverses the function of update_player(),
  294.    extracting data from the player gadgets and storing it in the
  295.    player's data structure
  296. */
  297.  
  298. void store_player()
  299. {  // store data from player gadgets into structure
  300.    // player name
  301.    strcpy(PLAYER.name,
  302.       ((struct StringInfo *)namefield->SpecialInfo)->Buffer);
  303.    /*
  304.       NOTE: no need to update player type, as this is kept up
  305.       to date in the main gadget-handling functions
  306.       production efficiency.  However, the "show" value is derived
  307.       from it and should be updated.
  308.    */
  309.    if (ISHUMAN(PLAYER.type))
  310.       PLAYER.show = SHOW_ALL;
  311.    else
  312.       PLAYER.show = SHOW_NON;
  313.    PLAYER.prod = ((struct StringInfo *)prod_int->SpecialInfo)->LongInt;
  314.    // attack modifier
  315.    PLAYER.att = ((struct StringInfo *)att_int->SpecialInfo)->LongInt;
  316.    // defense modifier
  317.    PLAYER.def = ((struct StringInfo *)def_int->SpecialInfo)->LongInt;
  318.    // computer aggressiveness
  319.    PLAYER.aggr = ((struct StringInfo *)aggr_int->SpecialInfo)->LongInt;
  320. }
  321.  
  322.  
  323. /*
  324.    toggle_pgad() handles the choice of a certain player for the user
  325.    to edit or view -- it fiddles with the number-gadget image and then
  326.    updates the other player gadgets
  327. */
  328.  
  329. void toggle_pgad(hit_gad)
  330. UWORD hit_gad;
  331. {
  332.    short ctr;
  333.  
  334.    if (hit_gad <1 || hit_gad>8)
  335.       return;
  336.    for (ctr=1; ctr<=8; ctr++) {
  337.       if (ctr==hit_gad)
  338.          select(pgads[ctr]);
  339.       else
  340.          unselect(pgads[ctr]);
  341.    OD
  342.    ZapGList(pgads[1],opt_window,8);
  343.    RefreshGList(pgads[1],opt_window,NULL,8);
  344.    show_depress(pgads[hit_gad],opt_window->RPort);
  345.    store_player();
  346.    player = hit_gad;
  347.    update_player();
  348. }
  349.  
  350.  
  351. // add_player() is the function associated with the [+] button
  352.  
  353. void add_player()
  354. {  // increment the number of players
  355.    high_player++;
  356.    // if we are at the maximum number, then disable the plus gadget
  357.    if (high_player>=8) {
  358.       disable(plus_gad);
  359.       ZapGList(plus_gad,opt_window,1);
  360.       RefreshGList(plus_gad,opt_window,NULL,1);
  361.    FI
  362.    // if the minus gadget is disabled, then enable it
  363.    if (disabled(minus_gad)) {
  364.       enable(minus_gad);
  365.       ZapGList(minus_gad,opt_window,1);
  366.       RefreshGList(minus_gad,opt_window,NULL,1);
  367.    FI
  368.    enable(pgads[high_player]);
  369.    ZapGList(pgads[1],opt_window,8);
  370.    RefreshGList(pgads[1],opt_window,NULL,8);
  371.    show_depress(pgads[player],opt_window->RPort);
  372. }
  373.  
  374.  
  375. // subtract_player is the function associated with the [-] button
  376.  
  377. void subtract_player()
  378. {  // decrement the number of players
  379.    disable(pgads[high_player]);
  380.    high_player--;
  381.    // if the currently selected player is being removed, then
  382.    // deselect him and select the next lower player
  383.    if (player > high_player) {
  384.        unselect(pgads[player]);
  385.        store_player();
  386.        player--;
  387.        select(pgads[player]);
  388.        update_player();
  389.    FI
  390.    // if we now have the minimum number of players, then
  391.    // disable the minus gadget
  392.    if (high_player<=2) {
  393.       disable(minus_gad);
  394.       ZapGList(minus_gad,opt_window,1);
  395.       RefreshGList(minus_gad,opt_window,NULL,1);
  396.    FI
  397.    // if the plus gadget is disabled, then enable it
  398.    if (disabled(plus_gad)) {
  399.       enable(plus_gad);
  400.       ZapGList(plus_gad,opt_window,1);
  401.       RefreshGList(plus_gad,opt_window,NULL,1);
  402.    FI
  403.    ZapGList(pgads[1],opt_window,8);
  404.    RefreshGList(pgads[1],opt_window,NULL,8);
  405.    show_depress(pgads[player],opt_window->RPort);
  406. }
  407.  
  408.  
  409. void av_update_gadget(av_button)
  410. struct Gadget *av_button;
  411. {
  412.    int color, destx, desty;
  413.    int av_icon = av_button->GadgetID;
  414.  
  415.    destx = av_button->LeftEdge+1;
  416.    desty = av_button->TopEdge+1;
  417.  
  418.    switch (av_icon) {
  419.       case ARMOR:
  420.          color = GREEN;
  421.          break;
  422.       case AIRCAV:
  423.       case BOMBER:
  424.       case FIGHTER:
  425.          color = LT_BLUE;
  426.          break;
  427.       case DESTROYER:
  428.       case CRUISER:
  429.       case BATTLESHIP:
  430.       case CARRIER:
  431.       case SUB:
  432.          color = DK_BLUE;
  433.          break;
  434.       case LANDMINE:
  435.          bevel_box(destx-1,desty-1,21,17,opt.landmines);
  436.          SetAPen(rast_port,GREEN);  SetDrMd(rast_port,JAM1);
  437.          RectFill(rast_port,destx,desty,destx+18,desty+14);
  438.          px_plot_landmine(destx+3,desty+4);
  439.          if (!opt.landmines) {   // stamp down the "banned" icon
  440.             SetAPen(rast_port,RED);
  441.             BltPattern(rast_port,(PLANEPTR)banned_mask,destx+1,desty+1,destx+17,desty+13,4);
  442.          FI
  443.          return;
  444.       case SEAMINE:
  445.          bevel_box(destx-1,desty-1,21,17,opt.seamines);
  446.          SetAPen(rast_port,DK_BLUE);  SetDrMd(rast_port,JAM1);
  447.          RectFill(rast_port,destx,desty,destx+18,desty+14);
  448.          px_plot_seamine(destx+5,desty+3);
  449.          if (!opt.seamines) {   // stamp down the "banned" icon
  450.             SetAPen(rast_port,RED);
  451.             BltPattern(rast_port,(PLANEPTR)banned_mask,destx+1,desty+1,destx+17,desty+13,4);
  452.          FI
  453.          return;
  454.       default:
  455.          return;
  456.    };
  457.    // for military units only -- not mines
  458.    px_plot_icon(av_icon,destx,desty,color,ORDER_NONE,FALSE);
  459.    if (wishbook[av_icon].enabled)
  460.       bevel_box(destx-1,desty-1,21,17,TRUE);    // show depressed
  461.    else {
  462.       SetAPen(rast_port,RED);    // blit on the red "banned" symbol
  463.       BltPattern(rast_port,(PLANEPTR)banned_mask,destx+1,desty+1,destx+17,desty+13,4);
  464.    FI
  465. }
  466.  
  467.  
  468. // edit_options() is the big, monster function in this program module
  469. // it's mostly window and gadget-handling stuff
  470.  
  471. BOOL edit_options()
  472. {
  473.    int ctr;
  474.    BOOL success;
  475.  
  476.    // structures for gadtools
  477.    struct Gadget *context, *okay_gad, *cancel_gad;
  478.    struct Gadget *rol_gametype; // , *rol_stacking;
  479.    struct Gadget *defend_cities, *allow_fortify, *use_stacking;
  480.    struct Gadget *av_armor, *av_aircav, *av_bomber, *av_fighter, *av_destroyer,
  481.                  *av_cruiser, *av_battleship, *av_carrier, *av_sub, *av_landmine,
  482.                  *av_seamine;
  483.    struct NewGadget generic = {
  484.       0,32,
  485.       18,13,
  486.       NULL,NULL,
  487.       0,
  488.       NULL,NULL,NULL
  489.    };
  490.    struct NewGadget button = {
  491.       159,219, // leftedge, topedge
  492.       85,14,   // width, height
  493.       "Continue",    // text label
  494.       &topaz11bold,  // font
  495.       1,             // gadget ID
  496.       PLACETEXT_IN,  // flags
  497.       NULL,NULL   // visual info, user data
  498.    };
  499.    struct NewGadget rollo = {
  500.       416,34, // leftedge, topedge
  501.       108,14, // width, height
  502.       "Game Play:",     // text label
  503.       &topaz11,   // font
  504.       2,          // gadget ID
  505.       PLACETEXT_LEFT,
  506.       NULL,NULL      // visual info, user data
  507.    };
  508.    struct NewGadget check = {
  509.       335,52,
  510.       26,11,
  511.       "Use _Stacking Rules?",
  512.       &topaz11,
  513.       3,
  514.       PLACETEXT_RIGHT,
  515.       NULL,NULL
  516.    };
  517.    struct NewGadget stringfield = {
  518.       77,50,
  519.       217,15,
  520.       "_Name:",
  521.       &topaz11,
  522.       4,
  523.       PLACETEXT_LEFT,
  524.       NULL,NULL
  525.    };
  526.    struct NewGadget slider = {
  527.       34,103,
  528.       205,13,
  529.       NULL,
  530.       &topaz11,
  531.       5,
  532.       NULL,
  533.       NULL,NULL
  534.    };
  535.    struct NewGadget intfield = {
  536.       250,102,
  537.       44,15,
  538.       NULL, // "%",
  539.       NULL, // &topaz11,
  540.       6,
  541.       PLACETEXT_RIGHT,
  542.       NULL,NULL
  543.    };
  544.    struct NewGadget av_button = {   // unit AVailability buttons
  545.       372,157,    // location of first active button (ARMOR)
  546.       21,17,      // standard height and width of AO buttons
  547.       NULL,       // no text
  548.       NULL,       // no font
  549.       ARMOR,      // gadget ID
  550.       NULL,       // ng_Flags (no text, so NULL it)
  551.       NULL,       // ng_VisualInfo (must be initialized dynamically)
  552.       NULL,       // ng_UserData
  553.    };
  554.  
  555.    init_players();
  556.  
  557.    high_player = 2;
  558.    player = 1;
  559.  
  560.    // make sure user doesn't play with the map window now
  561.    SetPointer(map_window,BUSY_POINTER);
  562.    ModifyIDCMP(map_window,NULL);
  563.  
  564.    // create the [Continue] and [Abort Game] buttons
  565.    if (!CreateContext(&context))
  566.       clean_exit(1,"Unable to create context gadget!");
  567.    button.ng_VisualInfo = vi;
  568.    button.ng_TextAttr = &topaz11bold;
  569.    okay_gad = CreateGadget(BUTTON_KIND,context,&button,TAG_END);
  570.    button.ng_LeftEdge = 325;
  571.    button.ng_Width = 100;
  572.    button.ng_GadgetText = "Abort Game";
  573.    button.ng_TextAttr = &topaz11;
  574.    button.ng_Flags = NULL;
  575.    cancel_gad = CreateGadget(BUTTON_KIND,okay_gad,&button,TAG_END);
  576.  
  577.    // the [Map] requester button
  578.    button.ng_LeftEdge = 327;
  579.    button.ng_TopEdge = 116;
  580.    button.ng_Width = 38;
  581.    button.ng_Height = 15;
  582.    button.ng_GadgetText = "Map";
  583.    mapfile_button = CreateGadget(BUTTON_KIND,cancel_gad,&button,TAG_END);
  584.  
  585.    // create the MANY player buttons
  586.    {
  587.       static struct IntuiText pgad_itext[10];
  588.       static char *numbers[] = { "-","1","2","3","4","5","6","7","8","+" };
  589.       static WORD blackvecs[] = { 1,12, 17,12, 17,0, 16,11, 16,1 };
  590.       static WORD whitevecs[] = { 16,0, 0,0, 0,12, 1,1, 1,11 };
  591.       static struct Border blackside = {
  592.          0,0,           // initial offsets from the origin
  593.          BLACK,GRAY,    // frontpen, backpen
  594.          JAM1,          // drawmode
  595.          5,             // number of vectors
  596.          blackvecs,     // black line vectors
  597.          NULL
  598.       };
  599.       static struct Border whiteside = {
  600.          0,0,           // initial offsets from the origin
  601.          WHITE,GRAY,    // frontpen, backpen
  602.          JAM1,          // drawmode
  603.          5,             // number of vectors
  604.          whitevecs,     // white line vectors
  605.          &blackside     // link to other border struct
  606.       };
  607.  
  608.       generic.ng_VisualInfo = vi;
  609.  
  610.       // create the minus player button
  611.       generic.ng_LeftEdge = 64;
  612.       pgad_itext[0].FrontPen = 1;
  613.       pgad_itext[0].BackPen = 0;
  614.       pgad_itext[0].DrawMode = JAM2,
  615.       pgad_itext[0].LeftEdge = 4,
  616.       pgad_itext[0].TopEdge = 3;
  617.       pgad_itext[0].ITextFont = &topaz9;
  618.       pgad_itext[0].IText = "-";
  619.       pgad_itext[0].NextText = NULL;
  620.       minus_gad = CreateGadget(GENERIC_KIND,mapfile_button,&generic,
  621.          TAG_END);
  622.       minus_gad->GadgetText = &pgad_itext[0];
  623.       minus_gad->GadgetType |= GTYP_BOOLGADGET;
  624.       minus_gad->Activation = GACT_IMMEDIATE | GACT_TOGGLESELECT;
  625.       minus_gad->Flags = GFLG_LABELITEXT | GFLG_GADGHNONE | GFLG_DISABLED;
  626.       minus_gad->GadgetRender = &whiteside;
  627.       minus_gad->GadgetID = 16;
  628.  
  629.       // create the plus player button
  630.       generic.ng_LeftEdge = 238;
  631.       pgad_itext[9].FrontPen = 1;
  632.       pgad_itext[9].BackPen = 0;
  633.       pgad_itext[9].DrawMode = JAM2,
  634.       pgad_itext[9].LeftEdge = 4,
  635.       pgad_itext[9].TopEdge = 3;
  636.       pgad_itext[9].ITextFont = &topaz9;
  637.       pgad_itext[9].IText = "+";
  638.       pgad_itext[9].NextText = NULL;
  639.       plus_gad = CreateGadget(GENERIC_KIND,minus_gad,&generic,
  640.          TAG_END);
  641.       plus_gad->GadgetText = &pgad_itext[9];
  642.       plus_gad->GadgetType |= GTYP_BOOLGADGET;
  643.       plus_gad->Activation = GACT_IMMEDIATE | GACT_TOGGLESELECT;
  644.       plus_gad->Flags = GFLG_LABELITEXT | GFLG_GADGHNONE;
  645.       plus_gad->GadgetRender = &whiteside;
  646.       plus_gad->GadgetID = 25;
  647.  
  648.       generic.ng_LeftEdge = 88;
  649.       pgads[0] = plus_gad;
  650.       for (ctr = 1; ctr<=8; ctr++) {
  651.          pgad_itext[ctr].FrontPen = 1;
  652.          pgad_itext[ctr].BackPen = 0;
  653.          pgad_itext[ctr].DrawMode = JAM2,
  654.          pgad_itext[ctr].LeftEdge = 5,
  655.          pgad_itext[ctr].TopEdge = 3;
  656.          pgad_itext[ctr].ITextFont = &topaz9;
  657.          pgad_itext[ctr].IText = numbers[ctr];
  658.          pgad_itext[ctr].NextText = NULL;
  659.  
  660.          pgads[ctr] = CreateGadget(GENERIC_KIND,pgads[ctr-1],&generic,
  661.             TAG_END);
  662.          pgads[ctr]->GadgetText = &pgad_itext[ctr];
  663.          pgads[ctr]->GadgetType |= GTYP_BOOLGADGET;
  664.          pgads[ctr]->Activation = GACT_IMMEDIATE | GACT_TOGGLESELECT;
  665.          pgads[ctr]->Flags = GFLG_LABELITEXT | GFLG_GADGHNONE;
  666.          if (ctr>high_player)
  667.             pgads[ctr]->Flags |= GFLG_DISABLED;
  668.          pgads[ctr]->GadgetRender = &whiteside;
  669.          pgads[ctr]->GadgetID = 16+ctr;
  670.          generic.ng_LeftEdge += generic.ng_Width;
  671.       OD
  672.       select(pgads[1]);
  673.    }
  674.  
  675.    // create rollo gadgets
  676.    {
  677.       static char *gametype_strings[] = { "Normal","File-Mail","Modem",NULL };
  678. //      static char *stacking_strings[] = { "None","Movement Only","Full",NULL };
  679.       static char *type_strings[] = { "Human", "Computer", NULL };
  680.  
  681.       rollo.ng_VisualInfo = vi;
  682.       rol_gametype = CreateGadget(CYCLE_KIND,pgads[8],&rollo,
  683.          GTCY_Labels, gametype_strings,
  684.          TAG_END );
  685. //      rollo.ng_TopEdge = 56;
  686. //      rollo.ng_Width = 140;
  687. //      rollo.ng_GadgetText = "Stacking:";
  688. //      rol_stacking = CreateGadget(CYCLE_KIND,rol_gametype,&rollo,
  689. //         GTCY_Labels, stacking_strings,
  690. //         TAG_END );
  691.       rollo.ng_LeftEdge = 76;
  692.       rollo.ng_TopEdge = 70;
  693.       rollo.ng_Width = 100;
  694.       rollo.ng_GadgetText = "_Type:";
  695.       rol_ptype = CreateGadget(CYCLE_KIND,rol_gametype,&rollo,
  696.          GTCY_Labels, type_strings,
  697.          GT_Underscore, '_',
  698.          TAG_END );
  699.    }
  700.  
  701.    // create checkmark gadgets
  702.    check.ng_VisualInfo = vi;
  703.    use_stacking = CreateGadget(CHECKBOX_KIND,rol_ptype,&check,
  704.          GT_Underscore, '_',
  705.          TAG_END);
  706.    check.ng_TopEdge += 13;
  707.    check.ng_GadgetText = "_Defend Cities?";
  708.    defend_cities = CreateGadget(CHECKBOX_KIND,use_stacking,&check,
  709.          GT_Underscore, '_',
  710.          TAG_END);
  711.    check.ng_TopEdge += 13;
  712.    check.ng_GadgetText = "Allow _Fortification?";
  713.    allow_fortify = CreateGadget(CHECKBOX_KIND,defend_cities,&check,
  714.          GT_Underscore, '_',
  715.          TAG_END);
  716.  
  717.    // creating string gadget for player's name
  718.    stringfield.ng_VisualInfo = vi;
  719.    namefield = CreateGadget(STRING_KIND,allow_fortify,&stringfield,
  720.       GTST_String, roster[1].name,
  721.       GTST_MaxChars, 40L,
  722.       STRINGA_Justification, GACT_STRINGCENTER,
  723.       GT_Underscore, '_',
  724.       TAG_END);
  725.  
  726.    // create the slider gadgets
  727.    slider.ng_VisualInfo = vi;
  728.    prod_slide = CreateGadget(SLIDER_KIND,namefield,&slider,
  729.       GTSL_Min,   1,
  730.       GTSL_Max,   100,
  731.       GTSL_Level, 50,
  732.       GA_RelVerify, TRUE,
  733.       TAG_END);
  734.    prod_slide->GadgetID = 30;
  735.    slider.ng_TopEdge += 30;
  736.    att_slide = CreateGadget(SLIDER_KIND,prod_slide,&slider,
  737.       GTSL_Min,   -8,
  738.       GTSL_Max,   8,
  739.       GTSL_Level, 0,
  740.       GA_RelVerify, TRUE,
  741.       TAG_END);
  742.    att_slide->GadgetID = 31;
  743.    slider.ng_TopEdge += 30;
  744.    def_slide = CreateGadget(SLIDER_KIND,att_slide,&slider,
  745.       GTSL_Min,   -8,
  746.       GTSL_Max,   8,
  747.       GTSL_Level, 0,
  748.       GA_RelVerify, TRUE,
  749.       TAG_END);
  750.    def_slide->GadgetID = 32;
  751.    slider.ng_TopEdge += 30;
  752.    aggr_slide = CreateGadget(SLIDER_KIND,def_slide,&slider,
  753.       GTSL_Min,   1,
  754.       GTSL_Max,   10,
  755.       GTSL_Level, 5,
  756.       GA_RelVerify, TRUE,
  757.       GA_Disabled, TRUE,
  758.       TAG_END);
  759.    aggr_slide->GadgetID = 33;
  760.  
  761.    // create the integer gadgets
  762.    intfield.ng_VisualInfo = vi;
  763.    prod_int = CreateGadget(INTEGER_KIND,aggr_slide,&intfield,
  764.       GTIN_Number, 50,
  765.       GTIN_MaxChars, 3,
  766.       GA_TabCycle, TRUE,
  767.       TAG_END);
  768.    prod_int->GadgetID = 40;
  769.    intfield.ng_TopEdge += 30;
  770.    att_int = CreateGadget(INTEGER_KIND,prod_int,&intfield,
  771.       GTIN_Number, 0,
  772.       GTIN_MaxChars, 3,
  773.       GA_TabCycle, TRUE,
  774.       TAG_END);
  775.    att_int->GadgetID = 41;
  776.    intfield.ng_TopEdge += 30;
  777.    def_int = CreateGadget(INTEGER_KIND,att_int,&intfield,
  778.       GTIN_Number, 0,
  779.       GTIN_MaxChars, 3,
  780.       GA_TabCycle, TRUE,
  781.       TAG_END);
  782.    def_int->GadgetID = 42;
  783.    intfield.ng_TopEdge += 30;
  784.    aggr_int = CreateGadget(INTEGER_KIND,def_int,&intfield,
  785.       GTIN_Number, 5,
  786.       GTIN_MaxChars, 3,
  787.       GA_TabCycle, TRUE,
  788.       GA_Disabled, TRUE,
  789.       TAG_END);
  790.    aggr_int->GadgetID = 43;
  791.  
  792.    // create string gadget for map filename
  793.    stringfield.ng_LeftEdge = 374;
  794.    stringfield.ng_TopEdge = 116;
  795.    stringfield.ng_Width = 207;
  796.    stringfield.ng_Height = 15;
  797.    stringfield.ng_GadgetText = NULL;
  798.    strcpy(foo,map_filepath);
  799.    if (strlen(foo))
  800.       if (map_filepath[strlen(foo)-1]!='/' && map_filepath[strlen(foo)-1]!=':')
  801.             strcat(foo,"/");
  802.    strcat(foo,map_filename);
  803.    mapfile_field = CreateGadget(STRING_KIND,aggr_int,&stringfield,
  804.       GTST_String,   foo,
  805.       GTST_MaxChars, 128L,
  806.       STRINGA_Justification, GACT_STRINGCENTER,
  807.       TAG_END);
  808.  
  809.    /*
  810.       Create the ua_button gadgets, beginning with armor.
  811.       NOTE: The RIFLE and TRANSPORT buttons are not real.  They are only here
  812.       for decoration, since those units must always be available in the game.
  813.       By default, the FIGHTER, DESTROYER, CRUISER, BATTLESHIP, SUB, and CARRIER
  814.       are enabled -- units which were available in the original Empire game.
  815.       New units default to disabled: ARMOR, AIRCAV, BOMBER and mines.
  816.  
  817.       This is where it's tempting to build some kind of loop -- but probably
  818.       not worth the effort.  I'll just go down the list instead.
  819.    */
  820.    av_button.ng_VisualInfo = vi;
  821.    av_armor = CreateGadget(GENERIC_KIND,mapfile_field,&av_button,TAG_END);
  822.    av_armor->Flags |= GFLG_GADGHCOMP;
  823.    av_armor->Activation |= GACT_RELVERIFY;
  824.    wishbook[ARMOR].enabled = FALSE;
  825.  
  826.    av_button.ng_LeftEdge = 408;
  827.    av_button.ng_GadgetID = AIRCAV;
  828.    av_aircav = CreateGadget(GENERIC_KIND,av_armor,&av_button,TAG_END);
  829.    av_aircav->Flags |= GFLG_GADGHCOMP;
  830.    av_aircav->Activation |= GACT_RELVERIFY;
  831.    wishbook[AIRCAV].enabled = FALSE;
  832.  
  833.    av_button.ng_LeftEdge = 444;
  834.    av_button.ng_GadgetID = BOMBER;
  835.    av_bomber = CreateGadget(GENERIC_KIND,av_aircav,&av_button,TAG_END);
  836.    av_bomber->Flags |= GFLG_GADGHCOMP;
  837.    av_bomber->Activation |= GACT_RELVERIFY;
  838.    wishbook[BOMBER].enabled = FALSE;
  839.  
  840.    av_button.ng_LeftEdge = 480;
  841.    av_button.ng_GadgetID = FIGHTER;
  842.    av_fighter = CreateGadget(GENERIC_KIND,av_bomber,&av_button,TAG_END);
  843.    av_fighter->Flags |= GFLG_GADGHCOMP|GFLG_SELECTED;
  844.    av_fighter->Activation |= GACT_RELVERIFY;
  845.    wishbook[FIGHTER].enabled = TRUE;
  846.  
  847.    av_button.ng_LeftEdge = 552;
  848.    av_button.ng_GadgetID = LANDMINE;
  849.    av_landmine = CreateGadget(GENERIC_KIND,av_fighter,&av_button,TAG_END);
  850.    av_landmine->Flags |= GFLG_GADGHCOMP;
  851.    av_landmine->Activation |= GACT_RELVERIFY;
  852.    opt.landmines = FALSE;
  853.  
  854.    av_button.ng_LeftEdge = 372;     av_button.ng_TopEdge = 185;
  855.    av_button.ng_GadgetID = DESTROYER;
  856.    av_destroyer = CreateGadget(GENERIC_KIND,av_landmine,&av_button,TAG_END);
  857.    av_destroyer->Flags |= GFLG_GADGHCOMP|GFLG_SELECTED;
  858.    av_destroyer->Activation |= GACT_RELVERIFY;
  859.    wishbook[DESTROYER].enabled = TRUE;
  860.  
  861.    av_button.ng_LeftEdge = 408;
  862.    av_button.ng_GadgetID = CRUISER;
  863.    av_cruiser = CreateGadget(GENERIC_KIND,av_destroyer,&av_button,TAG_END);
  864.    av_cruiser->Flags |= GFLG_GADGHCOMP|GFLG_SELECTED;
  865.    av_cruiser->Activation |= GACT_RELVERIFY;
  866.    wishbook[CRUISER].enabled = TRUE;
  867.  
  868.    av_button.ng_LeftEdge = 444;
  869.    av_button.ng_GadgetID = BATTLESHIP;
  870.    av_battleship = CreateGadget(GENERIC_KIND,av_cruiser,&av_button,TAG_END);
  871.    av_battleship->Flags |= GFLG_GADGHCOMP|GFLG_SELECTED;
  872.    av_battleship->Activation |= GACT_RELVERIFY;
  873.    wishbook[BATTLESHIP].enabled = TRUE;
  874.  
  875.    av_button.ng_LeftEdge = 480;
  876.    av_button.ng_GadgetID = CARRIER;
  877.    av_carrier = CreateGadget(GENERIC_KIND,av_battleship,&av_button,TAG_END);
  878.    av_carrier->Flags |= GFLG_GADGHCOMP|GFLG_SELECTED;
  879.    av_carrier->Activation |= GACT_RELVERIFY;
  880.    wishbook[CARRIER].enabled = TRUE;
  881.  
  882.    av_button.ng_LeftEdge = 516;
  883.    av_button.ng_GadgetID = SUB;
  884.    av_sub = CreateGadget(GENERIC_KIND,av_carrier,&av_button,TAG_END);
  885.    av_sub->Flags |= GFLG_GADGHCOMP|GFLG_SELECTED;
  886.    av_sub->Activation |= GACT_RELVERIFY;
  887.    wishbook[SUB].enabled = TRUE;
  888.  
  889.    av_button.ng_LeftEdge = 552;
  890.    av_button.ng_GadgetID = SEAMINE;
  891.    av_seamine = CreateGadget(GENERIC_KIND,av_sub,&av_button,TAG_END);
  892.    av_seamine->Flags |= GFLG_GADGHCOMP;
  893.    av_seamine->Activation |= GACT_RELVERIFY;
  894.    opt.seamines = FALSE;
  895.  
  896.    {
  897.       int watop, waleft;
  898.       #define WAWIDTH 607
  899.       #define WAHEIGHT 239
  900.  
  901.       watop = (map_screen->Height-WAHEIGHT)/2;
  902.       waleft = (map_screen->Width-WAWIDTH)/2;
  903.  
  904.       opt_window = OpenWindowTags(NULL,
  905.          WA_Gadgets,context,
  906.          WA_Title,"Starting a New Game",
  907.          WA_CustomScreen,map_screen,
  908.          WA_Top,watop,        WA_Left,waleft,
  909.          WA_Height,WAHEIGHT,  WA_Width,WAWIDTH,
  910.          WA_IDCMP,IDCMP_GADGETUP|IDCMP_GADGETDOWN|IDCMP_VANILLAKEY,
  911.          WA_Flags,NOCAREREFRESH|WFLG_DRAGBAR|WFLG_ACTIVATE,
  912.          TAG_END );
  913.       if (opt_window==NULL)
  914.          clean_exit(1,"ERROR: Unable to open options window!");
  915.       #undef WAWIDTH
  916.       #undef WAHEIGHT
  917.    }
  918.  
  919.    // render frames and text here
  920.    rast_port = opt_window->RPort;
  921.    frame(17,22,286,191,TRUE);
  922.    frame(316,22,276,191,TRUE);
  923.    plot_text(79,18," Player Information ",BLACK,LT_GRAY,JAM2,&topaz11);
  924.    plot_text(402,18," Game Options ",BLACK,LT_GRAY,JAM2,&topaz11);
  925.    plot_text(328,138,"Units Available:",BLACK,LT_GRAY,JAM1,&topaz11);
  926.    plot_text(28,90,"Production Efficiency:",BLACK,LT_GRAY,JAM1,&topaz11);
  927.    plot_text(29,120,"Attack Modifier:",BLACK,LT_GRAY,JAM1,&topaz11);
  928.    plot_text(29,150,"Defense Modifier:",BLACK,LT_GRAY,JAM1,&topaz11);
  929.    plot_text(28,180,"Computer Aggressiveness:",BLACK,LT_GRAY,JAM1,&topaz11);
  930.  
  931.    // render the color indicator icon
  932.    plot_text(201,74,"Color:",BLACK,LT_GRAY,JAM1,&topaz11);
  933.    px_plot_icon(RIFLE,260,72,PLAYER.color,ORDER_NONE,FALSE);
  934.    bevel_box(257,69,25,21,TRUE);
  935.  
  936.    // render the unit icons
  937.    // first the FAKE ones, just for decoration
  938.    px_plot_icon(RIFLE,337,158,GREEN,ORDER_NONE,FALSE);
  939.    bevel_box(336,157,21,17,TRUE);   // show depressed
  940.    bevel_frame(332,154,29,23,TRUE);
  941.    px_plot_icon(TRANSPORT,337,186,DK_BLUE,ORDER_NONE,FALSE);
  942.    bevel_box(336,185,21,17,TRUE);   // show depressed
  943.    bevel_frame(332,182,29,23,TRUE);
  944.  
  945.    // next I start on my av_button imagery, using the same function
  946.    // that updates them when the user messes with them
  947.    av_update_gadget(av_armor);
  948.    bevel_frame(368,154,29,23,FALSE);
  949.    av_update_gadget(av_aircav);
  950.    bevel_frame(404,154,29,23,FALSE);
  951.    av_update_gadget(av_bomber);
  952.    bevel_frame(440,154,29,23,FALSE);
  953.    av_update_gadget(av_fighter);
  954.    bevel_frame(476,154,29,23,FALSE);
  955.  
  956.    // THIS SPACE INTENTIALLY LEFT BLANK
  957.    bevel_box(512,154,29,23,TRUE);
  958.  
  959.    av_update_gadget(av_destroyer);
  960.    bevel_frame(368,182,29,23,FALSE);
  961.    av_update_gadget(av_cruiser);
  962.    bevel_frame(404,182,29,23,FALSE);
  963.    av_update_gadget(av_battleship);
  964.    bevel_frame(440,182,29,23,FALSE);
  965.    av_update_gadget(av_carrier);
  966.    bevel_frame(476,182,29,23,FALSE);
  967.    av_update_gadget(av_sub);
  968.    bevel_frame(512,182,29,23,FALSE);
  969.  
  970.    // next two spaces reserved for mines
  971.    av_update_gadget(av_landmine);
  972.    bevel_frame(548,154,29,23,FALSE);
  973.    av_update_gadget(av_seamine);
  974.    bevel_frame(548,182,29,23,FALSE);
  975.  
  976.    // select the current player's gadget
  977.    show_depress(pgads[1],opt_window->RPort);
  978.  
  979.    begin_message_loop:
  980.    {  // handle the user actions here
  981.       struct IntuiMessage *message; // the message the IDCMP sends us
  982.       struct Gadget *mygad;
  983.  
  984.       // useful for interpreting IDCMP messages
  985.       UWORD code;
  986.       ULONG class;
  987.       APTR object;
  988.       UWORD qualifier;
  989.  
  990.       FOREVER {
  991.          WaitPort(opt_window->UserPort);
  992.          while (message = GT_GetIMsg(opt_window->UserPort)) {
  993.             code = message->Code;  // MENUNUM
  994.             mygad = object = message->IAddress;  // Gadget
  995.             class = message->Class;
  996.             qualifier = message->Qualifier;
  997.             GT_ReplyIMsg(message);
  998.             if (class==IDCMP_VANILLAKEY) {
  999.                switch ((char)code) {
  1000.                   case 'v':
  1001.                      if ((qualifier & IEQUALIFIER_LCOMMAND)==0)
  1002.                         break;
  1003.                   case 'n':
  1004.                      ActivateGadget(namefield,opt_window,NULL);
  1005.                      break;
  1006.                   case 't':
  1007.                      // toggle the current player type HUMAN/COMPUTER
  1008.                      GT_SetGadgetAttrs(rol_ptype,opt_window,NULL,
  1009.                         GTCY_Active, ((PLAYER.type==COMPUTER) ? 0:1),
  1010.                         TAG_END);
  1011.                      change_ptype((PLAYER.type==COMPUTER) ? 0:1);
  1012.                      break;
  1013.                   case 'd':
  1014.                      // toggle the DEFEND CITIES gadget
  1015.                      setselect(defend_cities,!selected(defend_cities));
  1016.                      RefreshGList(defend_cities,opt_window,NULL,1);
  1017.                      break;
  1018.                   case 's':
  1019.                      // toggle the STACKING RULES gadget
  1020.                      setselect(use_stacking,!selected(use_stacking));
  1021.                      RefreshGList(use_stacking,opt_window,NULL,1);
  1022.                      break;
  1023.                   case 'f':
  1024.                      // toggle the FORTIFICATION gadget
  1025.                      setselect(allow_fortify,!selected(allow_fortify));
  1026.                      RefreshGList(allow_fortify,opt_window,NULL,1);
  1027.                      break;
  1028.                   case 13:
  1029.                      // show the button depressed
  1030.                      show_depress(okay_gad,opt_window->RPort);
  1031.                      Delay(10L);
  1032.                      success = TRUE;
  1033.                      goto exit_opt_window;
  1034.                   case 'b':
  1035.                      if ((qualifier & IEQUALIFIER_LCOMMAND)==0)
  1036.                         break;
  1037.                      show_depress(cancel_gad,opt_window->RPort);
  1038.                      Delay(10L);
  1039.                      success = FALSE;
  1040.                      goto exit_opt_window;
  1041.                   case '-':
  1042.                      if (disabled(minus_gad))
  1043.                         break;
  1044.                      show_depress(minus_gad,opt_window->RPort);
  1045.                      Delay(10L);
  1046.                      show_depress(minus_gad,opt_window->RPort);
  1047.                      subtract_player();
  1048.                      break;
  1049.                   case '+':
  1050.                      if (disabled(plus_gad))
  1051.                         break;
  1052.                      show_depress(plus_gad,opt_window->RPort);
  1053.                      Delay(10L);
  1054.                      show_depress(plus_gad,opt_window->RPort);
  1055.                      add_player();
  1056.                      break;
  1057.                }
  1058.                if ((char)code>=49 && (char)code<=56) {
  1059.                   int pnum = code-48;
  1060.                   if (pnum>high_player)
  1061.                      continue;
  1062.                   toggle_pgad(pnum);
  1063.                FI
  1064.             FI
  1065.             if (class==IDCMP_GADGETDOWN)
  1066.                if (mygad->GadgetID>=17 && mygad->GadgetID<=24)
  1067.                   toggle_pgad(mygad->GadgetID-16);
  1068.                if (mygad==minus_gad || mygad==plus_gad) {
  1069.                   show_depress((struct Gadget *)mygad,opt_window->RPort);
  1070.                   Delay(10L);
  1071.                   show_depress((struct Gadget *)mygad,opt_window->RPort);
  1072.                   if (object==plus_gad)
  1073.                      add_player();
  1074.                   if (object==minus_gad)
  1075.                      subtract_player();
  1076.                FI
  1077.             if (class==IDCMP_GADGETUP) {
  1078.                if (mygad->GadgetID>=30 && mygad->GadgetID<=33)
  1079.                   read_slider(mygad->GadgetID-30,code);
  1080.                if (mygad->GadgetID>=30 && mygad->GadgetID<=43)
  1081.                   read_integer(mygad->GadgetID-40);
  1082.                if (object==okay_gad) {
  1083.                   success = TRUE;
  1084.                   goto exit_opt_window;
  1085.                FI
  1086.                if (object==cancel_gad) {
  1087.                   success = FALSE;
  1088.                   goto exit_opt_window;
  1089.                FI
  1090.                if (object==rol_ptype)
  1091.                   change_ptype(code);
  1092.                if (object==rol_gametype)
  1093.                   change_gametype(code);
  1094.                if (object==mapfile_button) {
  1095.                   // call the ReqTools file requester for a map filename
  1096.                   struct rtFileRequester *req = NULL;
  1097.                   char pan[216];  // pan = Path And Name
  1098.                   BOOL chosen;
  1099.  
  1100.                   req = rtAllocRequestA(RT_FILEREQ,NULL);
  1101.                   if (req==NULL) {
  1102.                      alert(map_window,NULL,"Failed to allocate ReqTools file requester.","Drat!");
  1103.                      continue;
  1104.                   FI
  1105.  
  1106.                   rtChangeReqAttr(req,
  1107.                      RTFI_Dir,map_filepath,
  1108.                      RTFI_MatchPat,"#?.MAP",
  1109.                      TAG_END);
  1110.                   strcpy(pan,map_filename);
  1111.                   chosen = (BOOL)rtFileRequest(req,map_filename,"Select Map",
  1112.                      RTFI_Flags, FREQF_PATGAD,
  1113.                      RT_DEFAULT, TAG_END);
  1114.                   if (chosen) {
  1115.                      int dirlen = strlen(req->Dir);
  1116.                      strcpy(map_filepath,req->Dir);
  1117.                      strcpy(pan,map_filepath);
  1118.                      if (dirlen)
  1119.                         if (map_filepath[dirlen-1]!='/' && map_filepath[dirlen-1]!=':')
  1120.                            strcat(pan,"/");
  1121.                      strcat(pan,map_filename);
  1122.                      // copy pan into the string gadget
  1123.                      GT_SetGadgetAttrs(mapfile_field,opt_window,NULL,
  1124.                         GTST_String,   pan,
  1125.                         TAG_DONE);
  1126.                   FI
  1127.                   rtFreeRequest(req);
  1128.                FI
  1129.  
  1130.                if (object==av_armor) {
  1131.                   wishbook[ARMOR].enabled = !wishbook[ARMOR].enabled;
  1132.                   av_update_gadget(av_armor);
  1133.                FI
  1134.                if (object==av_aircav) {
  1135.                   wishbook[AIRCAV].enabled = !wishbook[AIRCAV].enabled;
  1136.                   av_update_gadget(av_aircav);
  1137.                FI
  1138.                if (object==av_bomber) {
  1139.                   wishbook[BOMBER].enabled = !wishbook[BOMBER].enabled;
  1140.                   av_update_gadget(av_bomber);
  1141.                FI
  1142.                if (object==av_fighter) {
  1143.                   wishbook[FIGHTER].enabled = !wishbook[FIGHTER].enabled;
  1144.                   av_update_gadget(av_fighter);
  1145.                FI
  1146.                if (object==av_destroyer) {
  1147.                   wishbook[DESTROYER].enabled = !wishbook[DESTROYER].enabled;
  1148.                   av_update_gadget(av_destroyer);
  1149.                FI
  1150.                if (object==av_cruiser) {
  1151.                   wishbook[CRUISER].enabled = !wishbook[CRUISER].enabled;
  1152.                   av_update_gadget(av_cruiser);
  1153.                FI
  1154.                if (object==av_battleship) {
  1155.                   wishbook[BATTLESHIP].enabled = !wishbook[BATTLESHIP].enabled;
  1156.                   av_update_gadget(av_battleship);
  1157.                FI
  1158.                if (object==av_carrier) {
  1159.                   wishbook[CARRIER].enabled = !wishbook[CARRIER].enabled;
  1160.                   av_update_gadget(av_carrier);
  1161.                FI
  1162.                if (object==av_sub) {
  1163.                   wishbook[SUB].enabled = !wishbook[SUB].enabled;
  1164.                   av_update_gadget(av_sub);
  1165.                FI
  1166.                if (object==av_landmine) {
  1167.                   opt.landmines = !opt.landmines;
  1168.                   av_update_gadget(av_landmine);
  1169.                FI
  1170.                if (object==av_seamine) {
  1171.                   opt.seamines = !opt.seamines;
  1172.                   av_update_gadget(av_seamine);
  1173.                FI
  1174.             FI
  1175.          OD
  1176.       OD
  1177.    }
  1178.    exit_opt_window:
  1179.  
  1180.    // flag the unused players
  1181.    for (ctr = high_player+1; ctr<=8; ctr++)
  1182.       roster[ctr].type = NOPLAYER;
  1183.  
  1184.    // store the active player's data
  1185.    store_player();
  1186.  
  1187.    // extract game option info from requester
  1188.  
  1189.    opt.defend_cities = selected(defend_cities);
  1190.    opt.fortification = selected(allow_fortify);
  1191.    opt.stacking = selected(use_stacking);
  1192.  
  1193.    // attempt to load the map
  1194.    if (success) {   // i.e. the user didn't cancel
  1195.       char *requested_fname;
  1196.  
  1197.       requested_fname = ((struct StringInfo *)mapfile_field->SpecialInfo)->Buffer;
  1198.       if (FLength(requested_fname)>0)
  1199.          success = load_map(requested_fname);
  1200.       else {
  1201.          int l;
  1202.  
  1203.          strcpy(foo,map_filepath);
  1204.          l = strlen(foo);
  1205.          if (l)
  1206.             if (map_filepath[l-1]!='/' && map_filepath[l-1]!=':')
  1207.                strcat(foo,"/");
  1208.          strcat(foo,map_filename);
  1209.          success = load_map(foo);
  1210.       FI
  1211.       // Now we need to test that the map selected has enough cities for
  1212.       //   all the players
  1213.       if( count_nodes(&city_list) < high_player ) {
  1214.          // Tell the user the bad news and put him back in the loop
  1215.          (void)rtEZRequestTags("Error! Map has too few cities.",
  1216.             "Okay",           NULL,              NULL,
  1217.             RT_Window,        map_window,
  1218.             RT_ReqPos,        REQPOS_CENTERSCR,
  1219.             RT_LockWindow,    TRUE,
  1220.             RTEZ_Flags,       EZREQF_CENTERTEXT,
  1221.             TAG_DONE );
  1222.          goto begin_message_loop;
  1223.       }
  1224.    }
  1225.  
  1226.    ClearPointer(map_window);
  1227.    ModifyIDCMP(map_window,IDCMP_MENUPICK);
  1228.  
  1229.    CloseWindow(opt_window);
  1230.    opt_window = NULL;
  1231.    rast_port = map_window->RPort;
  1232.    FreeGadgets(context);
  1233.    return success;
  1234. }
  1235.  
  1236. // end of listing
  1237.